"ui";

ui.layout(
    <vertical padding="16">
        <button id="ok" text="更新"/>
    </vertical>
);
//指定确定按钮点击时要执行的动作
ui.ok.click(function(){
    okHttpRequest("https://gitee.com/gx5/auto-demo/raw/master/Main.js", files.cwd()+"/Main.js",{
	    onDownloadSuccess: console.log('success'),
	    onDownloading: a => console.log(a),
	    onDownloadFailed: operation => operation(),
	}, {});
});


let threadsx = {
    starts(f, no_err_msg) {
        try {
            return threads.start(f);
        } catch (e) {
            let _regexp = /(Script)?InterruptedEx|script exiting/;
            if (!e.message.match(_regexp) && !no_err_msg) {
                throw Error(e);
            }
        }
    },
}

function  okHttpRequest(url, path, listener, params) {
    delete global._$_dialog_streaming_intrp_sgn;

    let {
        extra_headers: _headers,
        total_bytes: _par_t_bytes,
    } = params || {};

    let _t_bytes = threads.atomic(_par_t_bytes || -1);
    let _isTBytesAvail = () => _t_bytes.get() > 0;
    let _setDiagReceiver = (len) => {
        len > 0
        && _t_bytes.compareAndSet(-1, len)
        && $$func(_diagReceiver)
        && _diagReceiver(_diag, len);
    };

    let _thd_t_bytes_by_http = threadsx.starts(function () {
        while (!_isTBytesAvail()) {
            try {
                // may be -1 with a strong possibility
                let _len = http.get(url).headers["Content-Length"];
                _setDiagReceiver(_len);
            } catch (e) {
                sleep(200);
            }
        }
    });

    let _thd_t_bytes_by_url_cxn = threadsx.starts(function () {
        while (!_isTBytesAvail()) {
            try {
                let _cxn = new java.net.URL(url).openConnection();
                _cxn.setRequestProperty("Accept-Encoding", "identity");

                // may be -1 with a strong possibility
                let _len = _cxn.getContentLengthLong();
                _setDiagReceiver(_len);
                _cxn.disconnect();
            } catch (e) {
                sleep(200);
            }
        }
    });

    threadsx.starts(function () {
        let _client = new OkHttpClient();
        let _builder = new Packages.okhttp3.Request.Builder();
        if (_headers) {
            let _keys = Object.keys(_headers);
            let _k_len = _keys.length;
            for (let i = 0; i < _k_len; i += 1) {
                let _key = _keys[i];
                _builder.addHeader(_key, _headers[_key]);
            }
        }
        let _req = _builder.url(url).get().build();
        let _callback_o = {
            onResponse(call, res) {
                let {
                    BufferedInputStream: BIS,
                    BufferedOutputStream: BOS,
                } = java.io;

                let _buf_len = 1024;
                let _buf_bytes = java.lang.reflect.Array.newInstance(
                    java.lang.Byte.TYPE, _buf_len
                );
                let _read_bytes;
                let _acc_bytes = 0;
                let _bs, _fos, _bis, _bos;

                try {
                    let _code = res.code();
                    if (_code !== 200) {
                        return _errHandler(_code + " " + res.message());
                    }
                    _bs = res.body().byteStream();
                    _bis = new BIS(_bs);
                    _fos = new java.io.FileOutputStream(new java.io.File(path));
                    _bos = new BOS(_fos);
                    if (!_isTBytesAvail()) {
                        // may be -1 with a strong possibility
                        let _len = res.body().contentLength();
                        _setDiagReceiver(_len);
                    }

                    while (~(_read_bytes = _bis.read(_buf_bytes, 0, _buf_len))) {
                        if (global._$_dialog_streaming_intrp_sgn) {
                            global._$_dialog_streaming_intrp_sgn = false;
                            files.remove(path);
                            _bs.close();
                            return _errHandler("用户终止");
                        }
                        _fos.write(_buf_bytes, 0, _read_bytes);
                        _acc_bytes += _read_bytes;
                        if (_isTBytesAvail()) {
                            listener.onDownloading(_acc_bytes / _t_bytes * 100);
                        }
                    }
                    listener.onDownloadSuccess();
                } catch (err) {
                    _errHandler(err);
                } finally {
                    try {
                        _thd_t_bytes_by_http.interrupt();
                        _thd_t_bytes_by_url_cxn.interrupt();
                        _bos && _bos.close();
                        _fos.flush();
                        _fos && _fos.close();
                        _bis && _bis.close();
                        _bs && _bs.close();
                    } catch (err) {
                    }
                }

                // tool function(s) //
                function _errHandler(err) {
                    listener.onDownloadFailed(() => {
                        console.log(err)
                    });
                }
            },
            onFailure(call, err) {
               
            },
        };
        _client.newCall(_req).enqueue(
            new Packages.okhttp3.Callback(_callback_o)
        );
    });
}
